package com.heng;

import com.heng.commons.a1_过滤器.MyFilter;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

/**
 SpringApplication.run() -> refreshContext() -> refresh() -> ConfigurableApplicationContext.refresh() ->
 AbstractApplicationContext.refresh() -> finishBeanFactoryInitialization() ->
 DefaultListableBeanFactory.preInstantiateSingletons() -- 通过三级缓存创建单例bean.

 1.服务构建
    0. 在构造方法中
         this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
         this.webApplicationType = WebApplicationType.deduceFromClasspath();
         this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));

         // 初始化器和监听器 通过 spring.factories文件自动发现
         this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
         this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
         this.mainApplicationClass = this.deduceMainApplicationClass();

     1. 将资源加载器加载到内存中
     2. 确定服务器类型
    1. run方法
         public ConfigurableApplicationContext run(String... args) {
         Startup startup = SpringApplication.Startup.create();
         if (this.registerShutdownHook) {
         shutdownHook.enableShutdownHookAddition();
         }

         DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();

         ConfigurableApplicationContext context = null;
         this.configureHeadlessProperty();
         SpringApplicationRunListeners listeners = this.getRunListeners(args);
         listeners.starting(bootstrapContext, this.mainApplicationClass);

         ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);


         // 准备应用环境
         ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
         Banner printedBanner = this.printBanner(environment);
         context = this.createApplicationContext();
         context.setApplicationStartup(this.applicationStartup);

         this.callRunners(context, applicationArguments);  // CommandLineRunner接口

         if (context.isRunning()) {
         listeners.ready(context, startup.ready());

    2. refresh()  模板方法
         synchronized(this.startupShutdownMonitor) {
         StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
         this.prepareRefresh();

         // 创建bean工厂
         ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
         this.prepareBeanFactory(beanFactory);

         // 后置处理beanFactory
         this.postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

         // 调用后置处理方法
         this.invokeBeanFactoryPostProcessors(beanFactory);

         // 注册beanPostProcessors
         this.registerBeanPostProcessors(beanFactory);

         beanPostProcess.end();
         this.initMessageSource();
         this.initApplicationEventMulticaster();
         this.onRefresh();
         this.registerListeners();

         // 完成刷新
         this.finishRefresh();
         } catch (Error | RuntimeException var10) {
         if (this.logger.isWarnEnabled()) {
         this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
         }

         this.destroyBeans();
         this.cancelRefresh(var10);
         throw var10;
         } finally {
         contextRefresh.end();
 */
/*
启动类中的静态方法
main()方法前

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 // 版本信息
 :: Spring Boot ::                (v3.2.0)

2025-05-13T19:35:12.883+08:00  INFO 33808 --- [           main] com.heng.SpringBoot启动流程                  : Starting SpringBoot启动流程 using Java 20.0.2 with PID 33808 (D:\Gitee\Annotation\B_JAVA_SpringBoot\target\classes started by 86176 in D:\Gitee\Annotation)
2025-05-13T19:35:12.886+08:00  INFO 33808 --- [           main] com.heng.SpringBoot启动流程                  : No active profile set, falling back to 1 default profile: "default"
2025-05-13T19:35:13.332+08:00  INFO 33808 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2025-05-13T19:35:13.344+08:00  INFO 33808 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 JDBC repository interfaces.
2025-05-13T19:35:13.702+08:00  INFO 33808 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 4399 (http)
2025-05-13T19:35:13.703+08:00  INFO 33808 --- [           main] o.a.catalina.core.AprLifecycleListener   : An older version [1.2.39] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [2.0.5]
2025-05-13T19:35:13.703+08:00  INFO 33808 --- [           main] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.39] using APR version [1.7.4].
2025-05-13T19:35:13.708+08:00  INFO 33808 --- [           main] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 3.0.11 19 Sep 2023]
2025-05-13T19:35:13.714+08:00  INFO 33808 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-05-13T19:35:13.715+08:00  INFO 33808 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.16]
2025-05-13T19:35:13.747+08:00  INFO 33808 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-05-13T19:35:13.747+08:00  INFO 33808 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 809 ms
 */

@MapperScan("com.heng.dao.mapper")
@SpringBootApplication
public class SpringBootRunning {
    static {
        System.out.println("启动类中的静态方法");
    }
    public static void main(String[] args) {

        System.out.println("main()方法前");
        SpringApplication.run(SpringBootRunning.class);
        System.out.println("main()方法后");
    }

//    @Bean(initMethod = "init")
//    public TestAop E() {
//        return new TestAop();
//    }

//    @Bean
//    public FilterRegistrationBean<MyFilter> filterFilterRegistrationBean() {
//        FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
//        filterRegistrationBean.setFilter(new MyFilter());
//        filterRegistrationBean.addUrlPatterns("/test/*"); // 指定需要过滤的路径
//        return filterRegistrationBean;
//    }
}
